李守中

ZFS 基本操作

Table of Contents

1. ZFS 基础

1.1. Debian 安装 ZFS

/etc/apt/sources.list 里添加 contrib 仓库之后,执行 apt install zfsutils-linux 进行安装。

安装过程会往内核里加入 ZFS 支持。

1.2. 池管理基础

zpool create <pool_name> <pool_type> <device_name> 创建一个存储池。

zpool attach <pool_name> <device_in_pool> <device_name> 向池中添加一个设备使 strip 变成 mirror

zpool detach <pool_name> <pool_device_name> 让一个池中的设备脱离池。

zpool remove <pool_name> <pool_device_name> 从一个池中删除一个设备。

zpool offline <pool_name> <device_name> 让一个池中的设备离线。

zpool scrub <pool_name> 同步池中的数据后,检测池中数据的错误并修复。

zpool add <zpool_name> log <device> 给没有 SLOG 设备的池添加一个 SLOG 设备。

zpool attach <zpool_name> <log_device> <device> 向已有一个 SLOG 设备的池添加另一个 SLOG 设备使之互为镜像。

zpool add <zpool_name> log mirror <device_a> <device_b> 直接添加两个互为镜像的 SLOG 设备。

2. 快照

创建快照后,文件系统变成只读,只有文件块的引用改变后,zfs 才会使用硬盘空间记录被改变的文件块。

快照无法被直接使用,但可以被克隆、备份与回滚。

2.1. 创建与销毁快照

创建一个叫 datapool 的池:

# zpool create datapool mirror /dev/sdb /dev/sdc
# zpool list
NAME       SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
datapool  1.98G    65K  1.98G         -     0%     0%  1.00x  ONLINE  -

创建一个新的文件系统并挂载:

# zfs create datapool/docs -o mountpoint=/docs
# zfs list -r datapool
NAME            USED  AVAIL  REFER  MOUNTPOINT
datapool       93.5K  1.92G    19K  /datapool
datapool/docs    19K  1.92G    19K  /docs

快照名称格式为 <filesystem-name>@<snap-name><volume-name>@<snap-name> 。创建快照:

# zfs snapshot datapool/docs@version1
# zfs list -t snapshot
NAME                     USED  AVAIL  REFER  MOUNTPOINT
datapool/docs@version1      0      -  19.5K  -

datapool/docs 文件系统的一个名为 version1 的快照创建完成。

删除一个快照:

# zfs destroy datapool/docs@version1
# zfs list -t snapshot
no datasets available

2.2. 用快照回滚文件系统

模拟操作,先创建一个文件:

# echo "version 1" > /docs/data.txt
# cat /docs/data.txt
version 1

创建快照:

# zfs snapshot datapool/docs@version1
# zfs list -t snapshot
NAME                     USED  AVAIL  REFER  MOUNTPOINT
datapool/docs@version1     9K      -  19.5K  -

改变 /docs/data.txt 的内容:

# echo "version 2" > /docs/data.txt
# cat /docs/data.txt
version 2

回滚到 version1 快照:

# zfs list -t snapshot
NAME                     USED  AVAIL  REFER  MOUNTPOINT
datapool/docs@version1  9.50K      -  19.5K  -
# zfs rollback datapool/docs@version1
# cat /docs/data.txt
version 1

重命名快照:

# zfs rename datapool/docs@version1 datapool/docs@version2
# zfs list -t snapshot
NAME                     USED  AVAIL  REFER  MOUNTPOINT
datapool/docs@version2  9.50K      -  19.5K  -

注意: 当一个 dataset 存在快照时,无法直接删除。但可使用 -r 参数强制删除。

# zfs destroy datapool/docs
cannot destroy 'datapool/docs': filesystem has children
use '-r' to destroy the following datasets:
datapool/docs@version2

# zfs destroy -r datapool/docs
# zfs list -t snapshot
no datasets available

3. ZFS 克隆的创建与删除

克隆是一个可写卷或文件系统,其初始内容与被克隆的数据集相同。

克隆只能从快照中创建,在删除克隆以前,对应的快照无法删除。

创建一个克隆先要创建一个快照:

# zfs create datapool/docs -o mountpoint=/docs
# zfs list -r datapool
NAME            USED  AVAIL  REFER  MOUNTPOINT
datapool       93.5K  1.92G    19K  /datapool
datapool/docs    19K  1.92G    19K  /docs

# mkdir /docs/folder{1..5}
# ls /docs/
folder1  folder2  folder3  folder4  folder5

# zfs snapshot datapool/docs@today
# zfs list -t snapshot
NAME                  USED  AVAIL  REFER  MOUNTPOINT
datapool/docs@today      0      -    19K  -

从快照创建一个克隆:

# zfs clone datapool/docs@today datapool/pict
# zfs list
NAME            USED  AVAIL  REFER  MOUNTPOINT
datapool        166K  1.92G    19K  /datapool
datapool/docs    19K  1.92G    19K  /docs
datapool/pict     1K  1.92G    19K  /datapool/pict

在克隆线程结束以后,基于快照 datapool/docs@today 的数据已被克隆到 /datapool/pict。此时 /datapool/pict 与 /datapool/docs 中的数据相同:

# ls /datapool/pict
folder1  folder2  folder3  folder4  folder5

在删除克隆以前,对应的快照无法删除:

# zfs destroy datapool/docs@today
cannot destroy 'datapool/docs@today': snapshot has dependent clones
use '-R' to destroy the following datasets:
datapool/pict

要先删快照:

# zfs destroy datapool/pict

再删克隆:

# zfs destroy datapool/docs@today
# zfs list -t snapshot
no datasets available

4. ZFS 池复制

ZFS 池复制基于快照实现。快照可以随时被创建,数量不限。通过不断创建、传输和恢复快照,可以实现在一台或机器间同步池中数据。ZFS提供了一个内置的序列化功能,可以将数据以 stream 的形式发送到标准输出。

创建备份池:

# zpool create backuppool mirror sde sdf
# zpool list
NAME         SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
backuppool  1.98G    50K  1.98G         -     0%     0%  1.00x  ONLINE  -
datapool    1.98G   568K  1.98G         -     0%     0%  1.00x  ONLINE  -

检查池信息:

# zpool status
  pool: datapool
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        datapool    ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sdb     ONLINE       0     0     0
            sdc     ONLINE       0     0     0

errors: No known data errors

  pool: backuppool
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        backuppool    ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            sde     ONLINE       0     0     0
            sdf     ONLINE       0     0     0

errors: No known data errors

给要备份的 dataset 创建一个快照:

# zfs snapshot datapool/docs@today
# zfs list -t snapshot
NAME                  USED  AVAIL  REFER  MOUNTPOINT
datapool/docs@today      0      -    19K  -
# ls /docs/
folder1  folder2  folder3  folder4  folder5

复制开始:

# zfs send datapool/docs@today | zfs receive backuppool/backup
# zfs list
NAME                USED  AVAIL  REFER  MOUNTPOINT
backuppool           83K  1.92G    19K  /backuppool
backuppool/backup    19K  1.92G    19K  /backuppool/backup
datapool            527K  1.92G    19K  /datapool
datapool/docs        19K  1.92G    19K  /docs

# ls /backuppool/backup
folder1  folder2  folder3  folder4  folder5

把数据复制到其它机器:

# zfs send datapool/docs@today | ssh otherserver zfs recv backuppool/backup


Last Update: 2023-07-09 Sun 09:25

Generated by: Emacs 28.2 (Org mode 9.5.5)   Contact: [email protected]

若正文中无特殊说明,本站内容遵循: 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议